Skip to main content

Complex analysis

๐Ÿงฉ Complex Numbersโ€‹

z=a+biz = a + bi

var a = new ComplexNumber(3, 2);
var b = new ComplexNumber(5, 3);

var sum = a + b;
var product = a * b;
var power = a.Pow(2); // 5 + 12i

Exponential form (Euler's formula) โ€” eiฯ€=โˆ’1e^{i\pi} = -1

new ComplexNumber(0, Math.PI).Exponential(); // -1

๐ŸŒˆ Complex Functionsโ€‹

A ComplexFunction represents a mapping f:Cโ†’Cf: \mathbb{C} \to \mathbb{C} decomposed into its real and imaginary parts:

f(z)=u(x,y)+iโ€‰v(x,y)f(z) = u(x,y) + i\,v(x,y)

namespace Numerics.Objects

Constructing a ComplexFunction

From real/imaginary component functions:

var f = new ComplexFunction(
re: point => point.x * point.x - point.y * point.y, // u(x,y) = xยฒ - yยฒ
im: point => 2 * point.x * point.y // v(x,y) = 2xy
);

From a complex-valued function f(z)f(z):

var f = new ComplexFunction(z => z.Pow(2));  // f(z) = zยฒ

๐ŸŽจ Jacobianโ€‹

The Jacobian matrix of a complex function f=u+ivf = u + iv:

Jf=(โˆ‚uโˆ‚xโˆ‚uโˆ‚yโˆ‚vโˆ‚xโˆ‚vโˆ‚y)J_f = \begin{pmatrix} \frac{\partial u}{\partial x} & \frac{\partial u}{\partial y} \\ \frac{\partial v}{\partial x} & \frac{\partial v}{\partial y} \end{pmatrix}

var f = new ComplexFunction(z => z.Pow(2));
Matrix jacobian = f.Jacobian((1, 2));

๐ŸŒ€ Analyticity (Cauchyโ€“Riemann equations)โ€‹

A complex function is analytic (holomorphic) at a point if and only if the Cauchyโ€“Riemann equations hold:

โˆ‚uโˆ‚x=โˆ‚vโˆ‚y,โˆ‚uโˆ‚y=โˆ’โˆ‚vโˆ‚x\frac{\partial u}{\partial x} = \frac{\partial v}{\partial y}, \quad \frac{\partial u}{\partial y} = -\frac{\partial v}{\partial x}

var f = new ComplexFunction(z => z.Pow(2));
bool analytic = f.IsAnalytical((1, 2)); // true โ€” zยฒ is entire

var g = new ComplexFunction(
re: point => point.x * point.x + point.y * point.y, // |z|ยฒ
im: point => 0
);
bool notAnalytic = g.IsAnalytical((1, 1)); // false โ€” |z|ยฒ is not analytic

๐Ÿ”„ Quaternionโ€‹

Quaternions generalize complex numbers to 4 dimensions: q=w+xi+yj+zkq = w + xi + yj + zk. They are the standard representation for 3D rotations โ€” compact (4 doubles vs 9 for a matrix), numerically stable, and free of gimbal lock.

Algebraic hierarchy: R(double)โŠ‚C(ComplexNumber)โŠ‚H(Quaternion)โ„ (double) โŠ‚ โ„‚ (ComplexNumber) โŠ‚ โ„ (Quaternion)

// Create from axis + angle
var q = Quaternion.FromAxisAngle(new Vector(0, 0, 1), Math.PI / 2); // 90ยฐ about Z

// Rotate a vector: v' = qยทvยทq*
var rotated = q.Rotate(new Vector(1, 0, 0)); // โ†’ (0, 1, 0)

// Compose rotations via multiplication (non-commutative)
var q2 = Quaternion.FromAxisAngle(new Vector(0, 1, 0), Math.PI / 3);
var combined = q2 * q; // q first, then q2

// Convert to/from 3ร—3 rotation matrix
Matrix m = q.ToMatrix();
Quaternion recovered = Quaternion.FromMatrix(m);

// Euler angles (ZYX convention)
var q3 = Quaternion.FromEulerAngles(roll: 0.3, pitch: 0.5, yaw: 0.7);
var (roll, pitch, yaw) = q3.ToEulerAngles();

// Axis-angle round-trip
var (axis, angle) = q.ToAxisAngle();

๐Ÿงญ Frame Transforms

The FrameTransforms utility class provides coordinate frame transformations commonly used in flight dynamics and rigid-body simulation. It transforms between world (inertial), body (fixed to object), and wind (aligned with velocity) frames.

using CSharpNumerics.Numerics.Objects;

var attitude = Quaternion.FromEulerAngles(0.3, 0.5, 0.7);
var bodyVec = new Vector(1, 2, 3);

// Body frame โ†’ World frame: v_world = q ยท v ยท q*
Vector world = FrameTransforms.BodyToWorld(attitude, bodyVec);

// World frame โ†’ Body frame: v_body = q* ยท v ยท q
Vector body = FrameTransforms.WorldToBody(attitude, world);
// Round-trips perfectly: body โ‰ˆ bodyVec
double alpha = 0.1;  // angle of attack
double beta = 0.05; // sideslip angle
var v = new Vector(100, 5, 10);

Vector wind = FrameTransforms.BodyToWind(alpha, beta, v);
Vector back = FrameTransforms.WindToBody(alpha, beta, wind);
// Round-trips perfectly: back โ‰ˆ v
var bodyVelocity = new Vector(100, 5, 10);

double alpha = FrameTransforms.AngleOfAttack(bodyVelocity); // atan2(w, u)
double beta = FrameTransforms.SideslipAngle(bodyVelocity); // asin(v / |V|)

Matrix dcm = FrameTransforms.DCM(attitude); // 3ร—3 rotation matrix from quaternion
MethodDescription
BodyToWorld(q, v)Rotate vector from body to world frame
WorldToBody(q, v)Rotate vector from world to body frame
BodyToWind(ฮฑ, ฮฒ, v)Transform to wind frame using AoA and sideslip
WindToBody(ฮฑ, ฮฒ, v)Transform from wind frame back to body frame
AngleOfAttack(v)Compute ฮฑ from body-frame velocity
SideslipAngle(v)Compute ฮฒ from body-frame velocity
DCM(q)Quaternion to 3ร—3 rotation matrix

Interpolation:

// Spherical linear interpolation (constant angular velocity)
var halfway = Quaternion.Slerp(qStart, qEnd, 0.5);

// Normalized linear interpolation (cheaper, good for small angles)
var approx = Quaternion.Lerp(qStart, qEnd, 0.5);

Integration (for physics simulation):

// Integrate orientation with angular velocity ฯ‰ over time step dt
var q = Quaternion.Identity;
var omega = new Vector(0, 0, 1); // 1 rad/s about Z
q = Quaternion.IntegrateOrientation(q, omega, dt: 0.001);

Bridge from ComplexNumber:

// Embed โ„‚ into โ„ โ€” preserves complex multiplication
var c = new ComplexNumber(3, 2);
var q = Quaternion.FromComplexNumber(c); // (3, 2, 0, 0)